import re
from pathlib import Path
from os.path import expanduser
from os import unlink
import tempfile
from subprocess import call, Popen, DEVNULL
from subprocess import CompletedProcess, run, PIPE, CalledProcessError


def append_to_file(appendStr: str, filePath: str):
    with open(filePath, 'a') as f:
        f.write(appendStr)


def append_to_file_filter(append_str: str, file_path: str, filter_reg: str):
    c = re.compile(filter_reg)
    with open(file_path, 'r+') as f:
        lines = f.readlines()
        for l in range(len(lines)):
            if c.match(lines[l]):
                lines = lines[:l]
                break
        f.truncate(0)
        f.seek(0)
        f.writelines(lines)
        f.write(append_str)


def do2(args: str) -> Popen:
    log_file = args.split()[0]
    open(log_file, 'w').close()
    args = 'wrap ' + args
    return Popen(args, stdout=DEVNULL, stderr=DEVNULL, shell=True)


def do(args: []) -> CompletedProcess:
    open(args[0], 'w').close()
    args = ['wrap'] + args
    try:
        c = run(args, stdout=PIPE, stderr=PIPE, check=True)
        return c
    except CalledProcessError as e:
        # print(e.returncode)
        print(str(e.stderr, 'utf-8'))
        # report this exception
        ...


def do_bare(args: []) -> CompletedProcess:
    try:
        c = run(args, stdout=PIPE, stderr=PIPE, check=True)
        return c
    except CalledProcessError as e:
        print(str(e.stderr, 'utf-8'))


def common_do_with_log(args: []) -> CompletedProcess:
    args = ['/tmp/common.log'] + args
    return do(args)


def rar_file(file_path: str) -> str:
    rar_path = '.'.join(file_path.split('.')[:-1]) + '.rar'
    args = ['rar', 'a', '-ep', rar_path, file_path]
    common_do_with_log(args)
    return rar_path


def vim_edit(init_msg: str) -> str:
    tf = tempfile.NamedTemporaryFile(suffix=".tmp", delete=False)
    tf.write(bytes(init_msg, encoding='utf-8'))
    tf.close()

    call(['vim', tf.name])

    tf = open(tf.name, 'r')
    edited_str = tf.read()
    tf.close()
    unlink(tf.name)
    return edited_str


def combine_path(p: []) -> str:
    raw = '/'.join([i.strip('/') for i in p])
    if p[0][0] == '/':
        raw = '/' + raw
    return raw


def path_abs(p: str):
    return Path(expanduser(p)).absolute().__str__()


def path_attach_abs(p: str, attach: str):
    return Path(expanduser(p)).joinpath(attach).absolute().__str__()


def path_parent_abs(p: str):
    return Path(expanduser(p)).parent.absolute().__str__()


def dir_create(d: str):
    Path(d).mkdir(parents=True, exist_ok=True)


def split_ex(s: str, sep: str) -> []:
    dst = []
    for a in s.split(sep):
        e = a.strip()
        if not (len(e) == 0 or e.isspace()):
            dst.append(e)
    return dst
